import tensorflow as tf
import numpy as np
from cn.redguest.pbase.model.Dense import Dense as Dense

'''
此实例包含了两个分类，并包含了一个从网络从两个主网络通过一种无监督类似学习来学习网络的功能
两个主网络：
    输入向量维度：2
    输出向量维度：2
从网络：
    输入向量维度：2
    输出向量维度：4
'''


def main():
    bat_size = 1000
    train_num = 30000
    learning_speed = 1e-2
    tf_number_type = tf.float64
    np_number_type = np.float64

    x = tf.placeholder(tf_number_type)
    y = tf.placeholder(tf_number_type)

    l1 = Dense(x, 2, 2, tf.nn.tanh, d_type=tf_number_type)
    l2 = Dense(l1.y, 2, 3, tf.nn.tanh, d_type=tf_number_type)
    l3 = Dense(l2.y, 3, 2, d_type=tf_number_type)

    loss = tf.reduce_mean(tf.square(y - l3.y))
    optimizer = tf.train.GradientDescentOptimizer(learning_speed)
    train = optimizer.minimize(loss)

    l_l1 = Dense(x, 2, 2, tf.nn.tanh, d_type=tf_number_type)
    l_l2 = Dense(l_l1.y, 2, 3, tf.nn.tanh, d_type=tf_number_type)
    l_l3 = Dense(l_l2.y, 3, 2, d_type=tf_number_type)

    l_loss = tf.reduce_mean(tf.square(y - l_l3.y))
    l_optimizer = tf.train.GradientDescentOptimizer(learning_speed)
    l_train = l_optimizer.minimize(l_loss)

    c1 = Dense(x, 2, 3, tf.nn.tanh, d_type=tf_number_type)
    c2 = Dense(c1.y, 3, 4, tf.nn.sigmoid, d_type=tf_number_type)
    c2_1 = Dense(c2.y, 4, 5, tf.nn.sigmoid, d_type=tf_number_type)
    c2_2 = Dense(c2_1.y, 5, 4, tf.nn.sigmoid, d_type=tf_number_type)
    c3 = Dense(c2_2.y, 4, 4, d_type=tf_number_type)

    c_loss = tf.reduce_mean(tf.square(y - c3.y))
    c_optimizer = tf.train.GradientDescentOptimizer(learning_speed);
    c_train = c_optimizer.minimize(c_loss)

    init = tf.initialize_all_variables()

    s = tf.Session()
    s.run(init)

    merged = tf.summary.merge_all()  # 将图形、训练过程等数据合并在一起
    writer = tf.summary.FileWriter('logs', s.graph, flush_secs=10)  # 将训练日志写入到logs文件夹下

    train_x = np.random.rand(2 * bat_size).astype(np_number_type).reshape([bat_size, 2])
    train_y = np.matmul(train_x, [[1, 1], [1, -1]])
    l_train_y = np.matmul(train_x, [[2, 2], [1, -2]])

    print("--主方程1学习开始--")
    for i in range(train_num):
        _ = s.run(train, feed_dict={
            x: train_x,
            y: train_y
        })
        if i % 1000 == 0:
            print(str('%.2f' % (i / train_num * 100)) + "%")
    print("--主方程1学习结束--")
    print("--主方程2学习开始--")
    for i in range(train_num):
        _ = s.run(l_train, feed_dict={
            x: train_x,
            y: l_train_y
        })
        if i % 1000 == 0:
            print(str('%.2f' % (i / train_num * 100)) + "%")
    print("--主方程2学习结束--")
    '''
        生成噪音样本
    '''
    train_c_x = np.random.rand(2 * 2000).astype(np_number_type).reshape([2000, 2])
    train_c1_y = s.run(l3.y, feed_dict={
        x: train_c_x
    })
    train_c2_y = s.run(l_l3.y, feed_dict={
        x: train_c_x
    })

    print("--从方程学习开始--")
    for i in range(train_num):
        s.run(c_train, feed_dict={
            x: train_c_x,
            y: np.hstack((train_c1_y, train_c2_y))
        })
        if i % 1000 == 0:
            print(str('%.2f' % (i / train_num * 100)) + "%")
    print("--从方程学习结束--")
    print("--开始评价--")
    print("--主方程1输出评价--")
    print(s.run(l3.y, feed_dict={x: np.array([[0.3, 0.2], [0.1, 0.3], [0.5, 0.7]], dtype=np_number_type)}))

    print("--主方程2输出评价--")
    print(s.run(l_l3.y, feed_dict={x: np.array([[0.3, 0.2], [0.1, 0.3], [0.5, 0.7]], dtype=np_number_type)}))

    print("--从方程输出--")
    print(s.run(c3.y, feed_dict={x: np.array([[0.3, 0.2], [0.1, 0.3], [0.5, 0.7]], dtype=np_number_type)}))


if __name__ == "__main__":
    main()
